<!DOCTYPE html>
<html class="has-navbar-fixed-top">
<head>
    <meta charset="utf-8">
<title>Maven基础 - wanzixin</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/outdated-browser/1.1.5/outdatedbrowser.min.css">


<link href="/Study/Java/zh-cn/Maven%E5%9F%BA%E7%A1%80/" rel="alternate" hreflang="en" />
    


<meta name="description" content="">





    <meta name="description" content="Maven是一个Java项目管理和构建工具，它可以定义项目结构、项目依赖，并使用统一的方式进行自动化构建，是Java项目不可缺少的工具。本章我们详细介绍如何使用Maven。">
<meta property="og:type" content="article">
<meta property="og:title" content="Maven基础">
<meta property="og:url" content="https://wanzixin.github.io/Study/Java/zh-cn/Maven%E5%9F%BA%E7%A1%80/index.html">
<meta property="og:site_name" content="wanzixin">
<meta property="og:description" content="Maven是一个Java项目管理和构建工具，它可以定义项目结构、项目依赖，并使用统一的方式进行自动化构建，是Java项目不可缺少的工具。本章我们详细介绍如何使用Maven。">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2021-05-27T11:45:16.000Z">
<meta property="article:modified_time" content="2021-05-30T13:38:03.491Z">
<meta property="article:author" content="wanzixin">
<meta name="twitter:card" content="summary">





<link rel="icon" href="/favicon.png">


<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Ovo|Source+Code+Pro">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css">


<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.6.8/css/lightgallery.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/justifiedGallery/3.6.5/css/justifiedGallery.min.css">


<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-light.min.css">


<link rel="stylesheet" href="/css/style.css">


<script defer src="//use.fontawesome.com/releases/v5.0.8/js/all.js"></script>


    
    
    
    
    
    
    
    
    
    

    


<meta name="generator" content="Hexo 5.4.0"></head>
<body>
    
<nav class="navbar is-transparent is-fixed-top navbar-main" role="navigation" aria-label="main navigation">
    <div class="container">
        <div class="navbar-brand">
            <a class="navbar-item navbar-logo" href="/zh-cn">
                
                    
                    wanzixin
                    
                
            </a>
            <div class="navbar-burger">
                <span></span>
                <span></span>
                <span></span>
            </div>
        </div>
        
        <div class="navbar-menu navbar-start">
            
            <a class="navbar-item "
               href="/archives">Archives</a>
            
            <a class="navbar-item "
               href="/categories">Categories</a>
            
            <a class="navbar-item "
               href="/categories/Diary">Diary</a>
            
            <a class="navbar-item "
               href="/categories/Gallery">Gallery</a>
            
            <a class="navbar-item "
               href="/categories/Study">Study</a>
            
            <a class="navbar-item "
               href="/categories/Item">Item</a>
            
            <a class="navbar-item "
               href="/about">About</a>
            
        </div>
        
        <div class="navbar-menu navbar-end">
            
            <a class="navbar-item search" title="搜索" href="javascript:;">
                <i class="fas fa-search"></i>
            </a>
            
            
            <div class="navbar-item is-hoverable has-dropdown is-hidden-mobile is-hidden-tablet-only toc">
                <a class="navbar-item" title="目录">
                    <i class="fa fa-list"></i>
                </a>
                <div class="navbar-dropdown is-right">
                    
                    
                    
                    
                    <a class="navbar-item" href="#Maven介绍">1&nbsp;&nbsp;<b>Maven介绍</b></a>
                    
                    
                    
                    <a class="navbar-item" href="#Maven项目结构">1.1&nbsp;&nbsp;Maven项目结构</a>
                    
                    
                    <hr class="navbar-divider">
                    
                    
                    <a class="navbar-item" href="#依赖管理">2&nbsp;&nbsp;<b>依赖管理</b></a>
                    
                    
                    
                    <a class="navbar-item" href="#依赖关系">2.1&nbsp;&nbsp;依赖关系</a>
                    
                    
                    
                    <a class="navbar-item" href="#唯一ID">2.2&nbsp;&nbsp;唯一ID</a>
                    
                    
                    
                    <a class="navbar-item" href="#Maven镜像">2.3&nbsp;&nbsp;Maven镜像</a>
                    
                    
                    
                    <a class="navbar-item" href="#搜索第三方组件">2.4&nbsp;&nbsp;搜索第三方组件</a>
                    
                    
                    
                    <a class="navbar-item" href="#命令行编译">2.5&nbsp;&nbsp;命令行编译</a>
                    
                    
                    
                    <a class="navbar-item" href="#在IDE中使用Maven">2.6&nbsp;&nbsp;在IDE中使用Maven</a>
                    
                    
                    <hr class="navbar-divider">
                    
                    
                    <a class="navbar-item" href="#构建流程">3&nbsp;&nbsp;<b>构建流程</b></a>
                    
                    
                    
                    <a class="navbar-item" href="#Lifecycle和Phase">3.1&nbsp;&nbsp;Lifecycle和Phase</a>
                    
                    
                    
                    <a class="navbar-item" href="#Goal">3.2&nbsp;&nbsp;Goal</a>
                    
                    
                    
                    <a class="navbar-item" href="#小结">3.3&nbsp;&nbsp;小结</a>
                    
                    
                    <hr class="navbar-divider">
                    
                    
                    <a class="navbar-item" href="#使用插件">4&nbsp;&nbsp;<b>使用插件</b></a>
                    
                    
                    <hr class="navbar-divider">
                    
                    
                    <a class="navbar-item" href="#模块管理">5&nbsp;&nbsp;<b>模块管理</b></a>
                    
                    
                    
                    <a class="navbar-item" href="#中央仓库，私有仓库和本地仓库">5.1&nbsp;&nbsp;中央仓库，私有仓库和本地仓库</a>
                    
                    
                    
                    <a class="navbar-item" href="#本地仓库">5.1.1&nbsp;&nbsp;本地仓库</a>
                    
                    
                    <hr class="navbar-divider">
                    
                    
                    <a class="navbar-item" href="#使用mvnw">6&nbsp;&nbsp;<b>使用mvnw</b></a>
                    
                    
                    
                    <a class="navbar-item" href="#安装Maven-Wrapper">6.1&nbsp;&nbsp;安装Maven Wrapper</a>
                    
                    
                    <hr class="navbar-divider">
                    
                    
                    <a class="navbar-item" href="#发布Artifact">7&nbsp;&nbsp;<b>发布Artifact</b></a>
                    
                    
                    
                    <a class="navbar-item" href="#以静态文件发布">7.1&nbsp;&nbsp;以静态文件发布</a>
                    
                    
                    
                    <a class="navbar-item" href="#通过Nexus发布到中央仓库">7.2&nbsp;&nbsp;通过Nexus发布到中央仓库</a>
                    
                </div>
            </div>
            
            
            <a class="navbar-item" title="GitHub" target="_blank" rel="noopener" href="https://github.com/wanzixin">
                
                <i class="fab fa-github"></i>
                
            </a>
               
            
        </div>
    </div>
</nav>

    <section class="section">
    <div class="container">
    <article class="article content gallery" itemscope itemprop="blogPost">
    <h1 class="article-title is-size-3 is-size-4-mobile" itemprop="name">
        
            Maven基础
        
    </h1>
    <div class="article-meta columns is-variable is-1 is-multiline is-mobile is-size-7-mobile">
        <span class="column is-narrow">
            
                <span>5月 27 2021</span>
            
        </span>
        
        <span class="column is-narrow article-category">
            <i class="far fa-folder"></i>
            <a class="article-category-link" href="/zh-cn/categories/Study/">Study</a><span>></span><a class="article-category-link" href="/zh-cn/categories/Study/Java/">Java</a>
        </span>
        
        
        <span class="column is-narrow">
            
            
            40 分钟 读完 (约 6017 字)
        </span>
        
    </div>
    <div class="article-entry is-size-6-mobile" itemprop="articleBody">
    
        <html><head></head><body><p>Maven是一个Java项目管理和构建工具，它可以定义项目结构、项目依赖，并使用统一的方式进行自动化构建，是Java项目不可缺少的工具。本章我们详细介绍如何使用Maven。<span id="more"></span></p>
<h2 id="Maven介绍"><a href="#Maven介绍" class="headerlink" title="Maven介绍"></a>Maven介绍</h2><p>我们先来看看一个Java项目需要的东西。首先，我们需要确定引入哪些依赖包。其次，我们要确定项目的目录结构。例如，<code>src</code>目录存放Java源码，<code>resources</code>目录存放配置文件，<code>bin</code>目录存放编译后的生成的<code>.class</code>文件。此外，我们还需要配置环境，比如JDK的版本，编译打包流程，当前代码的版本号。最后，除了使用IDE编译外，我们还必须能通过命令行工具进行编译，才能让项目在一个独立的服务器上编译、测试、部署。</p>
<p>这些工作难度不大，但是非常繁琐和耗时。</p>
<p>Maven就是专门为Java项目打造的管理和构建工具。它的主要功能有：</p>
<ul>
<li>提供了一套标准化的项目结构</li>
<li>提供了一套标准化的构建流程（编译、测试、打包、发布……）</li>
<li>提供了一套依赖管理机制</li>
</ul>
<h3 id="Maven项目结构"><a href="#Maven项目结构" class="headerlink" title="Maven项目结构"></a>Maven项目结构</h3><p>一个使用Maven管理的普通的Java项目，它的目录结构默认如下：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs ascii">a-maven-project<br>├── pom.xml<br>├── src<br>│   ├── main<br>│   │   ├── java<br>│   │   └── resources<br>│   └── test<br>│       ├── java<br>│       └── resources<br>└── target<br></code></pre></td></tr></tbody></table></figure>

<p>根目录<code>a-maven-project</code>是项目名，它有一个项目描述文件<code>pom.xml</code>，<code>src/main/java</code>是存放Java源码的目录，<code>src/main/resources</code>是存放资源文件的目录，<code>src/test/java</code>是存放测试源码的目录，<code>src/test/resources</code>是存放测试资源的目录，最后，所有编译、打包生成的文件都在<code>target</code>目录里。</p>
<p>所有的目录结构都是约定好的标准结构，千万不要随意修改目录结构。标准结构无需任何配置就可以正常使用。</p>
<p>我们来看一下最关键的<code>pom.xml</code>，它长得像下面这样：</p>
<figure class="highlight java hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs java">&lt;project ...&gt;<br>	&lt;modelVersion&gt;<span class="hljs-number">4.0</span><span class="hljs-number">.0</span>&lt;/modelVersion&gt;<br>	&lt;groupId&gt;com.itranswarp.learnjava&lt;/groupId&gt;<br>	&lt;artifactId&gt;hello&lt;/artifactId&gt;<br>	&lt;version&gt;<span class="hljs-number">1.0</span>&lt;/version&gt;<br>	&lt;packaging&gt;jar&lt;/packaging&gt;<br>	&lt;properties&gt;<br>        ...<br>	&lt;/properties&gt;<br>	&lt;dependencies&gt;<br>        &lt;dependency&gt;<br>            &lt;groupId&gt;commons-logging&lt;/groupId&gt;<br>            &lt;artifactId&gt;commons-logging&lt;/artifactId&gt;<br>            &lt;version&gt;<span class="hljs-number">1.2</span>&lt;/version&gt;<br>        &lt;/dependency&gt;<br>	&lt;/dependencies&gt;<br>&lt;/project&gt;<br></code></pre></td></tr></tbody></table></figure>

<p>其中，<code>groupId</code>类似Java的包名，通常是公司或组织的名称，<code>artifactId</code>类似于Java的类名，通常是项目名称，再加上<code>version</code>。一个Maven工程就是由<code>groupId</code>，<code>artifactId</code>和<code>version</code>作为唯一标识。我们在引用其他第三方库时，也是通过这三个变量确定，例如，依赖<code>commons-logging</code>：</p>
<figure class="highlight java hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs java">&lt;dependency&gt;<br>    &lt;groupId&gt;commons-logging&lt;/groupId&gt;<br>    &lt;artifactId&gt;commons-logging&lt;/artifactId&gt;<br>    &lt;version&gt;<span class="hljs-number">1.2</span>&lt;/version&gt;<br>&lt;/dependency&gt;<br></code></pre></td></tr></tbody></table></figure>

<p>使用<code>&lt;dependency&gt;</code>声明一个依赖后，Maven就会自动下载这个依赖包并把它放到classpath中。</p>
<h2 id="依赖管理"><a href="#依赖管理" class="headerlink" title="依赖管理"></a>依赖管理</h2><p>如果我们的项目依赖第三方的jar包，例如commons logging，那么commons logging发布的jar包在哪下载？同样的，如果我们也依赖log4j，那么使用log4j需要哪些jar包？类似的依赖还包括JUnit，JavaMail。MySQL驱动等等，一个可行的方案是通过搜索引擎搜索到项目的官网，然后手动下载zip包，解压，放入classpath。但是，这个过程非常繁琐。</p>
<p>Maven解决了依赖管理。</p>
<p>例如，我们的项目依赖<code>abc</code>这个jar包，而<code>abc</code>又依赖<code>xyz</code>这个jar包。当我们声明了<code>abc</code>这个依赖时，Maven自动把<code>abc</code>和<code>xyz</code>都加入我们的项目依赖，不需要我们自己研究依赖关系。</p>
<p>Maven的第一个作用就是解决依赖管理。我们声明了自己的项目需要<code>abc</code>，Maven会自动导入<code>abc</code>的jar包，再判断出<code>abc</code>需要<code>xyz</code>，又会自动导入<code>xyz</code>的jar包，这样，最终我们的项目会依赖<code>abc</code>和<code>xyz</code>两个jar包。</p>
<p>我们来看一个复杂的依赖示例。</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.4.2.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>当我们声明一个spring-boot-starter-web依赖时，Maven会自动解析并判断最终需要二三十个其他的依赖。如果我们自己去手动管理这些依赖不仅耗时而且出错的概率也很大。</p>
<h3 id="依赖关系"><a href="#依赖关系" class="headerlink" title="依赖关系"></a>依赖关系</h3><p>Maven定义了几种依赖关系，分别是<code>compile</code>、<code>test</code>、<code>runtime</code>和<code>provided</code>。</p>
<table>
<thead>
<tr>
<th align="center">scope</th>
<th align="center">说明</th>
<th align="center">示例</th>
</tr>
</thead>
<tbody><tr>
<td align="center">compile</td>
<td align="center">编译时需要用到该jar包（默认）</td>
<td align="center">commons-logging</td>
</tr>
<tr>
<td align="center">test</td>
<td align="center">编译Test时需要用到该jar包</td>
<td align="center">junit</td>
</tr>
<tr>
<td align="center">runtime</td>
<td align="center">编译时不需要，但运行时需要用到</td>
<td align="center">mysql</td>
</tr>
<tr>
<td align="center">provided</td>
<td align="center">编译时需要用到，但运行时由JDK或某个服务器提供</td>
<td align="center">servlet-api</td>
</tr>
</tbody></table>
<p>其中，默认的<code>compile</code>是最常用的，Maven会把这种类型的依赖直接放入classpath。</p>
<p><code>test</code>依赖表示仅在测试时使用，正常运行时并不需要。最常用的<code>test</code>依赖就是JUnit。</p>
<p><code>runtime</code>依赖表示编译时不需要，但运行时需要。最典型的<code>runtime</code>依赖是JDBC驱动，例如MySQL驱动。</p>
<p><code>provided</code>依赖表示编译时需要，但运行时不需要。最典型的<code>provided</code>依赖是Servlet API，编译的时候需要，但是运行时，Servlet服务器内置了相关的jar，所以运行期不需要。</p>
<p>Maven如何知道从何处下载所需的依赖？也就是相关的jar包？答案是Maven维护了一个<a target="_blank" rel="noopener" href="https://repo1.maven.org/">中央仓库</a>，所有第三方库将自身的jar以及相关信息上传至中央仓库，Maven就可以从中央仓库把所需的依赖下载到本地。</p>
<p>Maven并不会每次都从中央仓库下载jar包。一旦一个jar包被下载过，就会被Maven自动缓存在本地目录，用户主目录的<code>.m2</code>目录，所以，除了第一次编译时需要下载需要时间会比较长，后续过程因为有本地存储，速度会快很多。</p>
<h3 id="唯一ID"><a href="#唯一ID" class="headerlink" title="唯一ID"></a>唯一ID</h3><p>对于某个依赖，Maven只需要3个变量即可唯一确定某个jar包：</p>
<ul>
<li>groupId：属于组织的名称，类似Java的包名；</li>
<li>artifactId：该jar包自身的名称，类似Java的类名；</li>
<li>version：该jar包的版本。</li>
</ul>
<p>通过上述3个变量，即可唯一确定某个jar包。Maven通过对jar包进行PGP签名确保任何一个jar包一经发布就无法修改。修改已发布jar包的唯一方法是发布一个新版本。</p>
<p>注：只有以<code>-SNAPSHOT</code>结尾的版本号会被Maven视为开发版本，开发版本每次都会重复下载，这种SNAPSHOT版本只能用于内部私有的Maven repo，公开发布的版本不允许出现SNAPSHOT。</p>
<h3 id="Maven镜像"><a href="#Maven镜像" class="headerlink" title="Maven镜像"></a>Maven镜像</h3><p>除了可以从Maven的中央仓库下载外，还可以从Maven的镜像仓库下载。如果访问Maven的中央仓库非常慢，我们可以选择一个速度较快的Maven的镜像仓库。Maven镜像仓库定期从中央仓库同步。</p>
<p>中国区用户可以使用阿里云提供的Maven镜像仓库。使用Maven镜像仓库需要一个配置，在用户主目录下进入<code>.m2</code>目录，创建一个<code>settings.xml</code>配置文件，内容如下：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">settings</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">mirrors</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">mirror</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>aliyun<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>aliyun<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">mirrorOf</span>&gt;</span>central<span class="hljs-tag">&lt;/<span class="hljs-name">mirrorOf</span>&gt;</span><br>            <span class="hljs-comment">&lt;!-- 国内推荐阿里云的Maven镜像 --&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">url</span>&gt;</span>https://maven.aliyun.com/repository/central<span class="hljs-tag">&lt;/<span class="hljs-name">url</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">mirror</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">mirrors</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">settings</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>配置镜像仓库后，Maven的下载速度会非常快。</p>
<h3 id="搜索第三方组件"><a href="#搜索第三方组件" class="headerlink" title="搜索第三方组件"></a>搜索第三方组件</h3><p>如果我们要引用一个第三方组件，如何确切地获得它的<code>groupId</code>，<code>artifactId</code>和<code>version</code>？可以在<a target="_blank" rel="noopener" href="https://search.maven.org/">https://search.maven.org/</a>搜索关键字，找到对应组件后，直接复制。</p>
<h3 id="命令行编译"><a href="#命令行编译" class="headerlink" title="命令行编译"></a>命令行编译</h3><p>在命令行中，进入到<code>pom.xml</code>所在目录，输入以下命令：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">$ mvn clean package<br></code></pre></td></tr></tbody></table></figure>

<p>如果一切顺利，即可在<code>target</code>目录下获得编译后自动打包的jar。</p>
<h3 id="在IDE中使用Maven"><a href="#在IDE中使用Maven" class="headerlink" title="在IDE中使用Maven"></a>在IDE中使用Maven</h3><p>几乎所有的IDE都内置了对Maven的支持。</p>
<h2 id="构建流程"><a href="#构建流程" class="headerlink" title="构建流程"></a>构建流程</h2><p>Maven不但有标准化的目录结构，而且还有一套标准化的构建流程，可以自动实现编译，打包，发布等等。</p>
<h3 id="Lifecycle和Phase"><a href="#Lifecycle和Phase" class="headerlink" title="Lifecycle和Phase"></a>Lifecycle和Phase</h3><p>我们首先了解什么是Maven的声明周期（lifecycle）。Maven的生命周期由一系列阶段（phase）构成，以内置的生命周期<code>default</code>为例，它包含以下phase。</p>
<ul>
<li>validate</li>
<li>initialize</li>
<li>generate-sources</li>
<li>process-sources</li>
<li>generate-resources</li>
<li>process-resources</li>
<li>compile</li>
<li>process-classes</li>
<li>generate-test-sources</li>
<li>process-test-sources</li>
<li>generate-test-resources</li>
<li>process-test-resources</li>
<li>test-compile</li>
<li>process-test-classes</li>
<li>test</li>
<li>prepare-package</li>
<li>package</li>
<li>pre-integration-test</li>
<li>integration-test</li>
<li>post-integration-test</li>
<li>verify</li>
<li>install</li>
<li>deploy</li>
</ul>
<p>如果我们运行<code>mvn package</code>，Maven就会执行<code>default</code>生命周期，它会从开始一直运行到<code>package</code>这个phase为止。</p>
<ul>
<li>validate</li>
<li>…</li>
<li>package</li>
</ul>
<p>如果我们运行<code>mvn compile</code>，Maven也会执行<code>default</code>生命周期，但这次它只会运行到<code>compile</code>，即以下几个phase：</p>
<ul>
<li>validate</li>
<li>…</li>
<li>compile</li>
</ul>
<p>Maven的另一个常用生命周期是<code>clean</code>，它会执行3个phase：</p>
<ul>
<li>pre-clean</li>
<li>clean （注意这个clean不是lifecycle而是phase）</li>
<li>post-clean</li>
</ul>
<p>所以，我们使用<code>mvn</code>这个命令时，后面的参数是phase，Maven自动根据生命周期运行到指定的phase。</p>
<p>更复杂的例子是指定多个phase，例如，运行<code>mvn clean package</code>，Maven先执行<code>clean</code>生命周期并运行到<code>clean</code>这个phase，然后执行<code>default</code>生命周期并运行到<code>package</code>这个phase，实际执行的phase如下：</p>
<ul>
<li>pre-clean</li>
<li>clean （注意这个clean是phase）</li>
<li>validate</li>
<li>…</li>
<li>package</li>
</ul>
<p>在实际开发过程中，经常使用的命令有：</p>
<p><code>mvn clean</code>：清理所有生成的class和jar；</p>
<p><code>mvn clean compile</code>：先清理，再执行到<code>compile</code>；</p>
<p><code>mvn clean test</code>：先清理，再执行到<code>test</code>，因为执行<code>test</code>前必须执行<code>compile</code>，所以这里不必指定<code>compile</code>；</p>
<p><code>mvn clean package</code>：先清理，再执行到<code>package</code>。</p>
<p>大多数phase在执行过程中，因为我们通常没有在<code>pom.xml</code>中配置相关的设置，所以这些phase什么事情都不做。</p>
<p>经常用到的phase其实只有几个：</p>
<ul>
<li>clean：清理</li>
<li>compile：编译</li>
<li>test：运行测试</li>
<li>package：打包</li>
</ul>
<h3 id="Goal"><a href="#Goal" class="headerlink" title="Goal"></a>Goal</h3><p>执行一个phase又会触发一个或多个goal：</p>
<table>
<thead>
<tr>
<th align="center">执行的Phase</th>
<th align="center">对应执行的Goal</th>
</tr>
</thead>
<tbody><tr>
<td align="center">compile</td>
<td align="center">compiler:compile</td>
</tr>
<tr>
<td align="center">test</td>
<td align="center">compiler:testCompile surefire:test</td>
</tr>
</tbody></table>
<p>goal的命名总是<code>abc:xyz</code>这种形式。</p>
<p>其实我们类比一下就明白了：</p>
<ul>
<li>lifecycle相当于Java的package，它包含一个或多个phase；</li>
<li>phase相当于Java的class，它包含一个或多个goal；</li>
<li>goal相当于class的method，它其实才是真正干活的。</li>
</ul>
<p>大多数情况下，我们只要指定phase，就默认执行这些phase默认绑定的goal，只有少数情况，我们可以直接运行一个goal，例如，启动Tomcat服务器。</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">mvn tomcat:run<br></code></pre></td></tr></tbody></table></figure>

<h3 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h3><p>Maven通过lifecycle、phase和goal来提供标准的构建流程。</p>
<p>最常用的构建命令是指定phase，然后让Maven执行到指定的phase：</p>
<ul>
<li>mvn clean</li>
<li>mvn clean compile</li>
<li>mvn clean test</li>
<li>mvn clean package</li>
</ul>
<p>通常情况，我们总是执行phase默认绑定的goal，因此不必指定goal。</p>
<h2 id="使用插件"><a href="#使用插件" class="headerlink" title="使用插件"></a>使用插件</h2><p>我们在前面介绍了Maven的lifecycle，phase和goal。使用Maven构建项目就是执行lifescycle，执行到指定的phase为止，每个phase会执行自己默认的一个或多个goal。goal是最小的任务单元。</p>
<p>我们以<code>compile</code>这个phase为例，执行：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">mvn compile<br></code></pre></td></tr></tbody></table></figure>

<p>Maven将执行<code>compile</code>这个phase，这个phase会调用<code>compile</code>插件执行关联的<code>compiler:compile</code>这个goal。</p>
<p>实际上，执行每个phase都是通过某个插件（<code>plugin</code>）执行的，Maven本身不知道如何执行<code>compile</code>，它只是负责找到对应的<code>compiler</code>插件，然后执行默认的<code>compiler:compile</code>这个goal来完成编译。所以，使用Maven，实际上就是配置好需要使用的插件，然后通过<code>phase</code>来调用它们。Maven已经内置了一些常用的标准插件：</p>
<table>
<thead>
<tr>
<th align="center">插件名称</th>
<th align="center">对应执行的phase</th>
</tr>
</thead>
<tbody><tr>
<td align="center">clean</td>
<td align="center">clean</td>
</tr>
<tr>
<td align="center">compiler</td>
<td align="center">compile</td>
</tr>
<tr>
<td align="center">surefire</td>
<td align="center">test</td>
</tr>
<tr>
<td align="center">jar</td>
<td align="center">package</td>
</tr>
</tbody></table>
<p>如果标准插件无法满足要求，我们还可以使用自定义插件。Maven通过自定义插件可以执行项目构建时需要的额外功能。使用自定义插件需要声明，例如，使用<code>maven-shade-plugin</code>可以创建一个可执行的jar，要使用这个插件，需要在<code>pom.xml</code>中声明：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">project</span>&gt;</span><br>    ...<br>	<span class="hljs-tag">&lt;<span class="hljs-name">build</span>&gt;</span><br>		<span class="hljs-tag">&lt;<span class="hljs-name">plugins</span>&gt;</span><br>			<span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span><br>				<span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>				<span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>maven-shade-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.2.1<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>				<span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span><br>					<span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span><br>						<span class="hljs-tag">&lt;<span class="hljs-name">phase</span>&gt;</span>package<span class="hljs-tag">&lt;/<span class="hljs-name">phase</span>&gt;</span><br>						<span class="hljs-tag">&lt;<span class="hljs-name">goals</span>&gt;</span><br>							<span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>shade<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span><br>						<span class="hljs-tag">&lt;/<span class="hljs-name">goals</span>&gt;</span><br>						<span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span><br>                            ...<br>						<span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span><br>					<span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span><br>				<span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span><br>			<span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span><br>		<span class="hljs-tag">&lt;/<span class="hljs-name">plugins</span>&gt;</span><br>	<span class="hljs-tag">&lt;/<span class="hljs-name">build</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">project</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>自定义插件往往需要一些配置，例如，<code>maven-shade-plugin</code>需要指定Java程序的入口，它的配置是：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">configuration</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">transformers</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">transformer</span> <span class="hljs-attr">implementation</span>=<span class="hljs-string">"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">mainClass</span>&gt;</span>com.itranswarp.learnjava.Main<span class="hljs-tag">&lt;/<span class="hljs-name">mainClass</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">transformer</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">transformers</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">configuration</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>Maven自带的标准插件是无需声明的，只有引入其他插件才需要声明。插件的配置和用法需参考插件的官方文档。</p>
<p>下面列举了一些常用的插件：</p>
<ul>
<li>maven-shade-plugin：打包所有依赖包并生成可执行jar；</li>
<li>cobertura-maven-plugin：生成单元测试覆盖率报告；</li>
<li>findbugs-maven-plugin：对Java源码进行静态分析以找出潜在问题。</li>
</ul>
<h2 id="模块管理"><a href="#模块管理" class="headerlink" title="模块管理"></a>模块管理</h2><p>在软件开发中，把一个大项目拆分为多个模块是降低软件复杂度的有效方法。Maven可以有效的管理多个模块，我们只需要把每个模块当成一个独立的Maven项目，他们有各自独立的<code>pom.xml</code>。</p>
<p>例如，A模块的pom.xml和B模块的pom.xml高度相似，可以提取出共同的部分作为<code>parent</code>。注意设置<code>&lt;packaging&gt;pom&lt;/packaging&gt;</code>，而不是<code>jar</code>。因为<code>parent</code>本身不包含任何的Java代码，编写<code>parent</code>的<code>pom.xml</code>只是为了在各个模块里简化配置。现在我们的工程目录如下：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs ascii">multiple-project<br>├── pom.xml<br>├── parent<br>│   └── pom.xml<br>├── module-a<br>│   ├── pom.xml<br>│   └── src<br>├── module-b<br>│   ├── pom.xml<br>│   └── src<br>└── module-c<br>    ├── pom.xml<br>    └── src<br></code></pre></td></tr></tbody></table></figure>

<p>这样就可以大幅简化配置文件的编写。</p>
<p>如果模块A依赖模块B，则模块A需要模块B的jar包才能正常编译，在模块A的<code>pom.xml</code>中就像这样：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs xml">...<br>  <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span><br>      <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.itranswarp.learnjava<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>module-b<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>          <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>      <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>  <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>最后，在编译的时候，需要在根目录创建一个<code>pom.xml</code>统一编译：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">project</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://maven.apache.org/POM/4.0.0"</span></span><br><span class="hljs-tag">    <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">"http://www.w3.org/2001/XMLSchema-instance"</span></span><br><span class="hljs-tag">    <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">modelVersion</span>&gt;</span>4.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">modelVersion</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.itranswarp.learnjava<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>build<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">packaging</span>&gt;</span>pom<span class="hljs-tag">&lt;/<span class="hljs-name">packaging</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>build<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">modules</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>parent<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>module-a<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>module-b<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">module</span>&gt;</span>module-c<span class="hljs-tag">&lt;/<span class="hljs-name">module</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">modules</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">project</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>这样，在根目录执行<code>mvn clean package</code>时，Maven会根据根目录的<code>pom.xml</code>找到包括<code>parent</code>在内的4个<code>module</code>，一次性全部编译。</p>
<h3 id="中央仓库，私有仓库和本地仓库"><a href="#中央仓库，私有仓库和本地仓库" class="headerlink" title="中央仓库，私有仓库和本地仓库"></a>中央仓库，私有仓库和本地仓库</h3><p>中央仓库和私有仓库略。</p>
<h4 id="本地仓库"><a href="#本地仓库" class="headerlink" title="本地仓库"></a>本地仓库</h4><p>本地仓库是指把本地开发的项目“发布”在本地，这样其他项目可以通过本地仓库引用它。但是我们不推荐把自己的模块安装到Maven的本地仓库，因为每次修改某个模块的源码，都需要重新安装，非常容易出现版本不一致的情况。更好的方法是使用模块化编译，在编译的时候，告诉Maven几个模块之间存在依赖关系，需要一块编译，Maven就会自动按依赖顺序编译这些模块。</p>
<h2 id="使用mvnw"><a href="#使用mvnw" class="headerlink" title="使用mvnw"></a>使用mvnw</h2><p><code>mvnw</code>时Maven Wrapper的缩写。我们安装Maven时，默认情况下，系统的所有项目都会使用全局安装的这个Maven版本。但是，对某个项目来说，可能必需要使用特定版本的Maven，这时，就可以使用<code>Maven Wrapper</code>。它负责给这个特定的项目安装指定版本的Maven，而其他项目不受影响。</p>
<p>简单来说，<code>Maven Wrapper</code>就是给一个项目提供一个独立的、指定版本的Maven供该项目使用。</p>
<h3 id="安装Maven-Wrapper"><a href="#安装Maven-Wrapper" class="headerlink" title="安装Maven Wrapper"></a>安装Maven Wrapper</h3><p>最简单的方式是在项目的根目录下运行安装命令：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">mvn -N io.takari:maven:0.7.6:wrapper<br></code></pre></td></tr></tbody></table></figure>

<p>它会自动使用最新版本的Maven。注意<code>0.7.6</code>是Maven Wrapper的版本，最新的版本可以去<a target="_blank" rel="noopener" href="https://github.com/takari/maven-wrapper">官方网站</a>查看。</p>
<p>如果要指定使用的Maven版本，使用下面的安装命令指定Maven的版本，例如<code>3.3.3</code>。</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">mvn -N io.takari:maven:0.7.6:wrapper -Dmaven=3.3.3<br></code></pre></td></tr></tbody></table></figure>

<p>安装后，查看项目结构：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs ascii">my-project<br>├── .mvn<br>│   └── wrapper<br>│       ├── MavenWrapperDownloader.java<br>│       ├── maven-wrapper.jar<br>│       └── maven-wrapper.properties<br>├── mvnw<br>├── mvnw.cmd<br>├── pom.xml<br>└── src<br>    ├── main<br>    │   ├── java<br>    │   └── resources<br>    └── test<br>        ├── java<br>        └── resources<br></code></pre></td></tr></tbody></table></figure>

<p>发现多了<code>mvnw</code>、<code>mvnw.cmd</code>和<code>.mvn</code>目录，我们只需要把<code>mvn</code>命令改为<code>mvnw</code>就可以使用跟项目关联的Maven。例如：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">mvnw clean package<br></code></pre></td></tr></tbody></table></figure>

<p>Maven Wrapper的另一个作用，是把项目的<code>mvnw</code>、<code>mvnw.cmd</code>和<code>.mvn</code>提交到版本库中，可以使所有的开发人员使用统一的Maven版本。</p>
<h2 id="发布Artifact"><a href="#发布Artifact" class="headerlink" title="发布Artifact"></a>发布Artifact</h2><p>当我们使用第三方开源库时，我们实际上是通过Maven自动下载它的jar包，并根据pom文件解析依赖，自动把相关依赖包都下载后加入到classpath。</p>
<p>那么，当我们自己写了一个开源库，非常希望别人也能使用时，总不能直接放个jar包的链接让别人下载吧？</p>
<p>如果我们把自己的开源库放到Maven的repo中，那么，别人只需按标准引用<code>groupId:artifactId:version</code>，即可自动下载jar包以及相关依赖。本节我们就来介绍如何发布一个库到Maven的repo中，介绍最常用的3种方法。</p>
<h3 id="以静态文件发布"><a href="#以静态文件发布" class="headerlink" title="以静态文件发布"></a>以静态文件发布</h3><p>如果我们观察一个中央仓库的Artifact结构，例如<a target="_blank" rel="noopener" href="https://commons.apache.org/proper/commons-math/">Commons Math</a>，它的groupId是<code>org.apache.commons</code>，artifactId是<code>commons-math3</code>，以版本<code>3.6.1</code>为例，发布在中央仓库的文件夹路径就是<a target="_blank" rel="noopener" href="https://repo1.maven.org/maven2/org/apache/commons/commons-math3/3.6.1/">https://repo1.maven.org/maven2/org/apache/commons/commons-math3/3.6.1/</a>，在此文件夹下，<code>commons-math3-3.6.1.jar</code>就是发布的jar包，<code>commons-math3-3.6.1.pom</code>就是它的<code>pom.xml</code>描述文件，<code>commons-math3-3.6.1-sources.jar</code>是源代码，<code>commons-math3-3.6.1-javadoc.jar</code>是文档。其它以<code>.asc</code>、<code>.md5</code>、<code>.sha1</code>结尾的文件分别是GPG签名、MD5摘要和SHA-1摘要。</p>
<p>我们只要按照这种目录结构组织文件，它就是一个有效的Maven仓库。</p>
<p>我们以一个项目为例，先创建Maven工程目录结构如下：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs ascii">how-to-become-rich<br>├── maven-repo        &lt;-- Maven本地文件仓库<br>├── pom.xml           &lt;-- 项目文件<br>├── src<br>│   ├── main<br>│   │   ├── java      &lt;-- 源码目录<br>│   │   └── resources &lt;-- 资源目录<br>│   └── test<br>│       ├── java      &lt;-- 测试源码目录<br>│       └── resources &lt;-- 测试资源目录<br>└── target            &lt;-- 编译输出目录<br></code></pre></td></tr></tbody></table></figure>

<p>在<code>pom.xml</code>里添加如下内容：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">project</span> <span class="hljs-attr">...</span>&gt;</span><br>    ...<br>    <span class="hljs-tag">&lt;<span class="hljs-name">distributionManagement</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">repository</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>local-repo-release<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>GitHub Release<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">url</span>&gt;</span>file://${project.basedir}/maven-repo<span class="hljs-tag">&lt;/<span class="hljs-name">url</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">repository</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">distributionManagement</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">build</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">plugins</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>maven-source-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span><br>                    <span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>attach-sources<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">phase</span>&gt;</span>package<span class="hljs-tag">&lt;/<span class="hljs-name">phase</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">goals</span>&gt;</span><br>                            <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>jar-no-fork<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span><br>                        <span class="hljs-tag">&lt;/<span class="hljs-name">goals</span>&gt;</span><br>                    <span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>maven-javadoc-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">executions</span>&gt;</span><br>                    <span class="hljs-tag">&lt;<span class="hljs-name">execution</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>attach-javadocs<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">phase</span>&gt;</span>package<span class="hljs-tag">&lt;/<span class="hljs-name">phase</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">goals</span>&gt;</span><br>                            <span class="hljs-tag">&lt;<span class="hljs-name">goal</span>&gt;</span>jar<span class="hljs-tag">&lt;/<span class="hljs-name">goal</span>&gt;</span><br>                        <span class="hljs-tag">&lt;/<span class="hljs-name">goals</span>&gt;</span><br>                    <span class="hljs-tag">&lt;/<span class="hljs-name">execution</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">executions</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">plugins</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">build</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">project</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>注意到<code>&lt;distributionManagement&gt;</code>，它指示了发布软件包的位置，这里的<code>&lt;url&gt;</code>是项目根目录下的<code>maven-repo</code>目录，在<code>&lt;build&gt;</code>中定义两个插件<code>maven-source-plugin</code>和<code>maven-javadoc-plugin</code>分别用来创建源码和javadoc。如果不想发布源码，可以把对应的插件去掉。</p>
<p>我们直接在项目根目录下运行Maven命令<code>mvn clean package deploy</code>，如果一切顺利，我们就可以在<code>maven-repo</code>目录下找到部署后的所有文件如下：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs ascii">maven-repo<br>└── com<br>    └── itranswarp<br>        └── rich<br>            └── how-to-become-rich<br>                ├── 1.0.0<br>                │   ├── how-to-become-rich-1.0.0-javadoc.jar<br>                │   ├── how-to-become-rich-1.0.0-javadoc.jar.md5<br>                │   ├── how-to-become-rich-1.0.0-javadoc.jar.sha1<br>                │   ├── how-to-become-rich-1.0.0-sources.jar<br>                │   ├── how-to-become-rich-1.0.0-sources.jar.md5<br>                │   ├── how-to-become-rich-1.0.0-sources.jar.sha1<br>                │   ├── how-to-become-rich-1.0.0.jar<br>                │   ├── how-to-become-rich-1.0.0.jar.md5<br>                │   ├── how-to-become-rich-1.0.0.jar.sha1<br>                │   ├── how-to-become-rich-1.0.0.pom<br>                │   ├── how-to-become-rich-1.0.0.pom.md5<br>                │   └── how-to-become-rich-1.0.0.pom.sha1<br>                ├── maven-metadata.xml<br>                ├── maven-metadata.xml.md5<br>                └── maven-metadata.xml.sha1<br></code></pre></td></tr></tbody></table></figure>

<p>最后一步，把这个项目推到GitHub上，并选择<code>Settings</code>-<code>GitHub Pages</code>，选择<code>master branch</code>启用Pages服务。</p>
<p>这样，把全部内容推送至GitHub后，即可作为静态网站访问Maven的repo，它的地址是<a target="_blank" rel="noopener" href="https://michaelliao.github.io/how-to-become-rich/maven-repo/">https://michaelliao.github.io/how-to-become-rich/maven-repo/</a>。版本<code>1.0.0</code>对应的jar包地址是：</p>
<figure class="highlight plaintext hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">https://michaelliao.github.io/how-to-become-rich/maven-repo/com/itranswarp/rich/how-to-become-rich/1.0.0/how-to-become-rich-1.0.0.jar<br></code></pre></td></tr></tbody></table></figure>

<p>现在，如果其他人希望引用这个Maven包，我们可以告知如下依赖即可：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.itranswarp.rich<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>how-to-become-rich<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>但是，除了正常导入依赖外，对方还需要再添加一个<code>&lt;repository&gt;</code>的声明，即使用方完整的<code>pom.xml</code>如下：</p>
<figure class="highlight xml hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">project</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://maven.apache.org/POM/4.0.0"</span></span><br><span class="hljs-tag">    <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">"http://www.w3.org/2001/XMLSchema-instance"</span></span><br><span class="hljs-tag">    <span class="hljs-attr">xsi:schemaLocation</span>=<span class="hljs-string">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">modelVersion</span>&gt;</span>4.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">modelVersion</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>example<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>how-to-become-rich-usage<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">packaging</span>&gt;</span>jar<span class="hljs-tag">&lt;/<span class="hljs-name">packaging</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">properties</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">maven.compiler.source</span>&gt;</span>11<span class="hljs-tag">&lt;/<span class="hljs-name">maven.compiler.source</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">maven.compiler.target</span>&gt;</span>11<span class="hljs-tag">&lt;/<span class="hljs-name">maven.compiler.target</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">java.version</span>&gt;</span>11<span class="hljs-tag">&lt;/<span class="hljs-name">java.version</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">properties</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">repositories</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">repository</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">id</span>&gt;</span>github-rich-repo<span class="hljs-tag">&lt;/<span class="hljs-name">id</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>The Maven Repository on Github<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">url</span>&gt;</span>https://michaelliao.github.io/how-to-become-rich/maven-repo/<span class="hljs-tag">&lt;/<span class="hljs-name">url</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">repository</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">repositories</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.itranswarp.rich<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>how-to-become-rich<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.0.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">project</span>&gt;</span><br></code></pre></td></tr></tbody></table></figure>

<p>在<code>&lt;repository&gt;</code>中，我们必须声明发布的Maven的repo地址，其中<code>&lt;id&gt;</code>和<code>&lt;name&gt;</code>可以任意填写，<code>&lt;url&gt;</code>填入GitHub Pages提供的地址+<code>/maven-repo/</code>后缀。现在，即可正常引用这个库并编写代码如下：</p>
<figure class="highlight java hljs"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs java">Millionaire millionaire = <span class="hljs-keyword">new</span> Millionaire();<br>System.out.println(millionaire.howToBecomeRich());<br></code></pre></td></tr></tbody></table></figure>

<p>有的童鞋会问，为什么使用<code>commons-logging</code>等第三方库时，并不需要声明repo地址？这是因为这些库都是发布到Maven中央仓库的，发布到中央仓库后，不需要告诉Maven仓库地址，因为它知道中央仓库的地址默认是<a target="_blank" rel="noopener" href="https://repo1.maven.org/maven2/">https://repo1.maven.org/maven2/</a>，也可以通过<code>~/.m2/settings.xml</code>指定一个代理仓库地址以替代中央仓库来提高速度（参考<a target="_blank" rel="noopener" href="https://www.liaoxuefeng.com/wiki/1252599548343744/1309301178105890">依赖管理</a>的Maven镜像）。</p>
<p>因为GitHub Pages并不会把我们发布的Maven包同步到中央仓库，所以自然使用方必须手动添加一个我们提供的仓库地址。</p>
<p>此外，通过GitHub Pages发布Maven repo时需要注意一点，即不要改动已发布的版本。因为Maven的仓库是不允许修改任何版本的，对一个库进行修改的唯一方法是发布一个新版本。但是通过静态文件的方式发布repo，实际上我们是可以修改jar文件的，但最好遵守规范，不要修改已发布版本。</p>
<h3 id="通过Nexus发布到中央仓库"><a href="#通过Nexus发布到中央仓库" class="headerlink" title="通过Nexus发布到中央仓库"></a>通过Nexus发布到中央仓库</h3><p>此方法前期需要复杂的申请账号和项目的流程，后期需要安装调试GPG，但只要跑通流程，后续发布都只需要一行命令。</p>
<p>具体过程略，需要时再查看教程。</p>
</body></html>
    
    </div>
    
    
    <div class="columns is-mobile is-multiline article-nav">
        <span class="column is-12-mobile is-half-desktop  article-nav-prev">
            
            <a href="/Study/Java/zh-cn/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/">网络编程</a>
            
        </span>
        <span class="column is-12-mobile is-half-desktop  article-nav-next">
            
            <a href="/Study/Java/zh-cn/%E5%8A%A0%E5%AF%86%E4%B8%8E%E5%AE%89%E5%85%A8/">加密与安全</a>
            
        </span>
    </div>
    
</article>


<div class="sharebox">
    
<div class="sharethis-inline-share-buttons"></div>
<script type='text/javascript' src='//platform-api.sharethis.com/js/sharethis.js#property=608c1408daac690012507aa2&amp;product=sop' async='async'></script>

</div>



    </div>
</section>
    <footer class="footer">
    <div class="container">
        <div class="columns content">
            <div class="column is-narrow has-text-centered">
                &copy; 2021 wanzixin&nbsp;
                Powered by <a href="http://hexo.io/" target="_blank">Hexo</a> & <a
                        target="_blank" rel="noopener" href="http://github.com/ppoffice/hexo-theme-minos">Minos</a>
            </div>
            <div class="column is-hidden-mobile"></div>

            
            <div class="column is-narrow">
                <div class="columns is-mobile is-multiline is-centered">
                
                    
                <a class="column is-narrow has-text-black" title="GitHub" target="_blank" rel="noopener" href="https://github.com/ppoffice/hexo-theme-minos">
                    
                    GitHub
                    
                </a>
                
                </div>
            </div>
            
            
<div class="column is-narrow has-text-centered">
    <div class="dropdown is-up is-right is-hoverable" style="margin-top: -0.2em;">
        <div class="dropdown-trigger">
            <button class="button is-small" aria-haspopup="true" aria-controls="dropdown-menu7">
                <span class="icon">
                    <i class="fas fa-globe"></i>
                </span>
                <span>简体中文</span>
                <span class="icon is-small">
            <i class="fas fa-angle-down" aria-hidden="true"></i>
          </span>
            </button>
        </div>
        <div class="dropdown-menu has-text-left" role="menu">
            <div class="dropdown-content">
            
                <a href="/Study/Java/zh-cn/Maven%E5%9F%BA%E7%A1%80/" class="dropdown-item">
                    English
                </a>
            
                <a href="/zh-cn/Study/Java/zh-cn/Maven%E5%9F%BA%E7%A1%80/" class="dropdown-item">
                    简体中文
                </a>
            
            </div>
        </div>
    </div>
</div>

        </div>
    </div>
</footer>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment-with-locales.min.js"></script>

<!-- test if the browser is outdated -->
<div id="outdated">
    <h6>Your browser is out-of-date!</h6>
    <p>Update your browser to view this website correctly. <a id="btnUpdateBrowser" target="_blank" rel="noopener" href="http://outdatedbrowser.com/">Update my browser now </a></p>
    <p class="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/outdated-browser/1.1.5/outdatedbrowser.min.js"></script>
<script>
    $(document).ready(function () {
        // plugin function, place inside DOM ready function
        outdatedBrowser({
            bgColor: '#f25648',
            color: '#ffffff',
            lowerThan: 'flex'
        })
    });
</script>

<script>
    window.FontAwesomeConfig = {
        searchPseudoElements: true
    }
    moment.locale("zh-CN");
</script>


    
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-MML-AM_CHTML"></script>
<script>
    MathJax.Hub.Config({
        "HTML-CSS": {
            matchFontHeight: false
        },
        SVG: {
            matchFontHeight: false
        },
        CommonHTML: {
            matchFontHeight: false
        },
        tex2jax: {
            inlineMath: [
                ['$','$'],
                ['\\(','\\)']
            ]
        }
    });
</script>

    
    
    
    
<script src="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.6.8/js/lightgallery-all.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/justifiedGallery/3.6.5/js/jquery.justifiedGallery.min.js"></script>
<script>
    (function ($) {
        $(document).ready(function () {
            if (typeof($.fn.lightGallery) === 'function') {
                $('.article.gallery').lightGallery({ selector: '.gallery-item' });
            }
            if (typeof($.fn.justifiedGallery) === 'function') {
                $('.justified-gallery').justifiedGallery();
            }
        });
    })(jQuery);
</script>

    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script>
    <style>
        .hljs {
            position: relative;
        }

        .hljs .clipboard-btn {
            float: right;
            color: #9a9a9a;
            background: none;
            border: none;
            cursor: pointer;
        }

        .hljs .clipboard-btn:hover {
          color: #8a8a8a;
        }

        .hljs > .clipboard-btn {
            display: none;
            position: absolute;
            right: 4px;
            top: 4px;
        }

        .hljs:hover > .clipboard-btn {
            display: inline;
        }

        .hljs > figcaption > .clipboard-btn {
            margin-right: 4px;
        }
    </style>
    <script>
      $(document).ready(function () {
        $('figure.hljs').each(function(i, figure) {
          var codeId = 'code-' + i;
          var code = figure.querySelector('.code');
          var copyButton = $('<button>Copy <i class="far fa-clipboard"></i></button>');
          code.id = codeId;
          copyButton.addClass('clipboard-btn');
          copyButton.attr('data-clipboard-target-id', codeId);

          var figcaption = figure.querySelector('figcaption');

          if (figcaption) {
            figcaption.append(copyButton[0]);
          } else {
            figure.prepend(copyButton[0]);
          }
        })

        var clipboard = new ClipboardJS('.clipboard-btn', {
          target: function(trigger) {
            return document.getElementById(trigger.getAttribute('data-clipboard-target-id'));
          }
        });
        clipboard.on('success', function(e) {
          e.clearSelection();
        })
      })
    </script>

    
    

    



<script src="/js/script.js"></script>


    
    <div class="searchbox ins-search">
    <div class="searchbox-mask"></div>
    <div class="searchbox-container ins-search-container">
        <div class="searchbox-input-wrapper">
            <input type="text" class="searchbox-input ins-search-input" placeholder="站内搜索" />
            <span class="searchbox-close ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="searchbox-result-wrapper ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
    (function (window) {
        var INSIGHT_CONFIG = {
            TRANSLATION: {
                POSTS: '文章',
                PAGES: '页面',
                CATEGORIES: '分类',
                TAGS: '标签',
                UNTITLED: '(无标题)',
            },
            CONTENT_URL: '/content.zh-cn.json',
        };
        window.INSIGHT_CONFIG = INSIGHT_CONFIG;
    })(window);
</script>

<script src="/js/insight.js"></script>

    
</body>
</html>